import express from "express";
import bodyParser from "body-parser";
import UserRouter from "./router/RouterUser";
import ws from "websocket";
import { LogicCenter } from "./game/controller/LogicCenter";
import { EnumServiceType } from "../../common/enum/EnumServiceType";
import { CacheComponent } from "../../framework/service/Components/CacheComponent";
import { RPCComponent } from "../../framework/service/Components/RPCComponent";
import { IMsg } from "../../framework/service/Components/WorkOrderInfo";
import { ServiceBase } from "../../framework/service/ServiceBase";
import { Tools } from "../../framework/utils/Tools";

export class LogicServer extends ServiceBase {
    
    onStop(): void {
        
    }
    onStart(): void {

    }


    public type: EnumServiceType = EnumServiceType.Logic;

    public static entity: LogicServer = null;

    public async start(port: number): Promise<void> {
        super.start(port);
        this.addComponent(new CacheComponent());
        this.setUpdateEnabled(true, 1000);

        //this.startHttpServer();

        this.startWebSocketServer();
        LogicServer.entity = this;
        LogicCenter.inst.init();
        
    }


    private async startHttpServer(): Promise<void> {
        // 写一个中间件 拦截请求
        const app = express()

        const jsonParser = bodyParser.json();
        app.use(bodyParser.urlencoded({ extended: false }));
        app.use(jsonParser);
        
        app.use((req, res, next) => {

            res.header("Access-Control-Allow-Origin", "*");
            res.header("Access-Control-Allow-Headers", "X-Requested-With");
            res.header("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS");
            res.header("X-Powered-By", '3.2.1');
            // res.header('Connection', 'keep-alive');
            let isPost: boolean = false;
            // 判断请求是 get 还是 post
            if (req.method === "GET") {

            } else if (req.method === "POST") {
                isPost = true;
            }

            // if (req.url.indexOf("/user/login") <0 && req.url.indexOf("/user/register") <0 ) {

            //     // 校验session

            //     if (!DBManager.inst.verifySession(req.body.session)) {
            //         const sc: SC_SystemError = new SC_SystemError();
            //         sc.code = EnumErrorCode.Session_isInvalid;
            //         res.send(sc);
            //         return;
            //     }

            // }

            //检查请求的数据字段类型是否符合标准

            // const requestModel: any = ConstRequestBodyConfig[req.url.split("?")[0]];

            // if (!requestModel) {
            //     const sc: SC_SystemError = new SC_SystemError();
            //     sc.code = EnumErrorCode.Router_not_Exist;

            //     res.send(sc);
            //     return;
            // }


            // if (isPost){


            //     if (!ret) {
            //         const sc: SC_SystemError = new SC_SystemError();
            //         sc.code = EnumErrorCode.ErrorParams ;

            //         res.send(sc);
            //         return;
            //     }
            // }



            next();
        });

        app.use(UserRouter);
        const rpcPort: number = await Tools.getRPCPort(2990);
        const rpcComp: RPCComponent = <RPCComponent>this.getComponent(RPCComponent);
        rpcComp.setExternalHost("127.0.0.1", rpcPort);
        app.listen(rpcPort, () => {
            //DBManager.inst.connect();
            console.log(`server is started:${rpcPort}`);
        });

    }


    //**启动webscoket 服务 */
    private startWebSocketServer(): void {

        var http = require('http');

        let wsServer = null;

        var server = http.createServer((request, response) => {
            console.log((new Date()) + ' Received request for ' + request.url);
            response.writeHead(404);
            response.end();
        });
        server.listen(8080, function () {
            console.log((new Date()) + ' Server is listening on port 8080');
        });

        wsServer = new ws.server({
            httpServer: server,
            // You should not use autoAcceptConnections for production
            // applications, as it defeats all standard cross-origin protection
            // facilities built into the protocol and the browser.  You should
            // *always* verify the connection's origin and decide whether or not
            // to accept it.
            autoAcceptConnections: false
        });

        function originIsAllowed(origin) {
            // put logic here to detect whether the specified origin is allowed.
            return true;
        }

        wsServer.on('request', (request) => {
            if (!originIsAllowed(request.origin)) {
                // Make sure we only accept requests from an allowed origin
                request.reject();
                console.log((new Date()) + ' Connection from origin ' + request.origin + ' rejected.');
                return;
            }


            
            var connection = request.accept('echo-protocol', request.origin);
            console.log((new Date()) + ' Peer ' + connection.remoteAddress + ' connected.');
            console.log((new Date()) + ' Connection accepted.');
            connection.on('message',  (message)=> {
                if (message.type === 'utf8') {
                    console.log('Received Message: ' + message.utf8Data);

                    const data: IMsg = JSON.parse(message.utf8Data);
                    LogicCenter.inst.receiveTCPMessage(data, connection);

                    if (connection.onMessage) {
                        connection.onMessage(data);
                    }
                    //connection.sendUTF(message.utf8Data);

                }
                else if (message.type === 'binary') {
                    console.log('Received Binary Message of ' + message.binaryData.length + ' bytes');
                    connection.sendBytes(message.binaryData);
                }

            });
            connection.on('close',  (reasonCode, description)=> {
                console.log((new Date()) + ' Peer ' + connection.remoteAddress + ' disconnected.');

                if(connection.disconnected){
                    connection.disconnected();
                }
            });
        });
    }

    public onUpdate(dt: number): void {
        

    }
}